#include "hiredis2wrap.h"

int RedisCommandOK( redisContext *conn , int *ok , char *format , ... )
{
	va_list		valist ;
	redisReply	*reply = NULL ;
	int		nret = 0 ;
	
	va_start( valist , format );
	reply = redisvCommand( conn , format , valist ) ;
	va_end( valist );
	if( reply == NULL )
	{
		return HIREDIS2WRAP_ERROR_COMMAND;
	}
	else if( reply->type == REDIS_REPLY_STATUS )
	{
		if( STRICMP( reply->str , == , "OK" ) )
		{
			if( ok )
				(*ok) = 1 ;
		}
		else
		{
			if( ok )
				(*ok) = 0 ;
		}
		freeReplyObject( reply );
	}
	else
	{
		nret = reply->type ;
		freeReplyObject( reply );
		return nret;
	}
	
	return 0;
}

int RedisCommandInteger( redisContext *conn , int *integer , char *format , ... )
{
	va_list		valist ;
	redisReply	*reply = NULL ;
	int		nret = 0 ;
	
	va_start( valist , format );
	reply = redisvCommand( conn , format , valist ) ;
	va_end( valist );
	if( reply == NULL )
	{
		return HIREDIS2WRAP_ERROR_COMMAND;
	}
	else if( reply->type == REDIS_REPLY_INTEGER )
	{
		if( integer )
			(*integer) = reply->integer ;
		freeReplyObject( reply );
	}
	else
	{
		nret = reply->type ;
		freeReplyObject( reply );
		return nret;
	}
	
	return 0;
}

int RedisCommandDouble( redisContext *conn , double *d , char *format , ... )
{
	va_list		valist ;
	redisReply	*reply = NULL ;
	int		nret = 0 ;
	
	va_start( valist , format );
	reply = redisvCommand( conn , format , valist ) ;
	va_end( valist );
	if( reply == NULL )
	{
		return HIREDIS2WRAP_ERROR_COMMAND;
	}
	else if( reply->type == REDIS_REPLY_STRING )
	{
		if( d )
			(*d) = atof(reply->str) ;
		freeReplyObject( reply );
	}
	else
	{
		nret = reply->type ;
		freeReplyObject( reply );
		return nret;
	}
	
	return 0;
}

int RedisCommandString( redisContext *conn , char *buffer , int bufsize , char *format , ... )
{
	va_list		valist ;
	redisReply	*reply = NULL ;
	int		nret = 0 ;
	
	va_start( valist , format );
	reply = redisvCommand( conn , format , valist ) ;
	va_end( valist );
	if( reply == NULL )
	{
		return HIREDIS2WRAP_ERROR_COMMAND;
	}
	else if( reply->type == REDIS_REPLY_STRING )
	{
		if( reply->len > bufsize-1 )
			return HIREDIS2WRAP_ERROR_OVERFLOW;
		strcpy( buffer , reply->str );
		freeReplyObject( reply );
	}
	else
	{
		nret = reply->type ;
		freeReplyObject( reply );
		return nret;
	}
	
	return 0;
}

int RedisCommandStrdup( redisContext *conn , char **pptr , char *format , ... )
{
	va_list		valist ;
	redisReply	*reply = NULL ;
	int		nret = 0 ;
	
	va_start( valist , format );
	reply = redisvCommand( conn , format , valist ) ;
	va_end( valist );
	if( reply == NULL )
	{
		return HIREDIS2WRAP_ERROR_COMMAND;
	}
	else if( reply->type == REDIS_REPLY_STRING )
	{
		(*pptr) = strdup(reply->str) ;
		freeReplyObject( reply );
		if( pptr == NULL )
			return HIREDIS2WRAP_ERROR_ALLOC;
	}
	else
	{
		nret = reply->type ;
		freeReplyObject( reply );
		return nret;
	}
	
	return 0;
}

int RedisCommandStringToInteger( redisContext *conn , int *integer , char *format , ... )
{
	va_list		valist ;
	redisReply	*reply = NULL ;
	int		nret = 0 ;
	
	va_start( valist , format );
	reply = redisvCommand( conn , format , valist ) ;
	va_end( valist );
	if( reply == NULL )
	{
		return HIREDIS2WRAP_ERROR_COMMAND;
	}
	else if( reply->type == REDIS_REPLY_STRING )
	{
		if( integer )
			(*integer) = atoi(reply->str) ;
		freeReplyObject( reply );
	}
	else
	{
		nret = reply->type ;
		freeReplyObject( reply );
		return nret;
	}
	
	return 0;
}

int RedisCommandArray( redisContext *conn , int *p_elements , redisReply **pp_reply , char *format , ... )
{
	va_list		valist ;
	redisReply	*reply = NULL ;
	int		nret = 0 ;
	
	va_start( valist , format );
	reply = redisvCommand( conn , format , valist ) ;
	va_end( valist );
	if( reply == NULL )
	{
		return HIREDIS2WRAP_ERROR_COMMAND;
	}
	else if( reply->type == REDIS_REPLY_ARRAY )
	{
		if( p_elements )
			(*p_elements) = reply->elements ;
		if( pp_reply )
			(*pp_reply) = reply ;
	}
	else
	{
		nret = reply->type ;
		freeReplyObject( reply );
		return nret;
	}
	
	return 0;
}

int RedisArrayOK( redisReply *reply , int index , int *ok )
{
	if( reply->element[index]->type == REDIS_REPLY_STATUS )
	{
		if( STRICMP( reply->element[index]->str , == , "OK" ) )
		{
			if( ok )
				(*ok) = 1 ;
		}
		else
		{
			if( ok )
				(*ok) = 0 ;
		}
	}
	else
	{
		return reply->element[index]->type;
	}
	
	return 0;
}

int RedisArrayInteger( redisReply *reply , int index , int *integer )
{
	if( reply->element[index]->type == REDIS_REPLY_INTEGER )
	{
		if( integer )
			(*integer) = reply->element[index]->integer ;
	}
	else
	{
		return reply->element[index]->type;
	}
	
	return 0;
}

int RedisArrayDouble( redisReply *reply , int index , double *d )
{
	if( reply->element[index]->type == REDIS_REPLY_STRING )
	{
		if( d )
			(*d) = atof(reply->element[index]->str) ;
	}
	else
	{
		return reply->element[index]->type;
	}
	
	return 0;
}

int RedisArrayString( redisReply *reply , int index , char *buffer , int bufsize )
{
	if( reply->element[index]->type == REDIS_REPLY_STRING )
	{
		if( reply->element[index]->len > bufsize-1 )
			return HIREDIS2WRAP_ERROR_OVERFLOW;
		strcpy( buffer , reply->element[index]->str );
	}
	else
	{
		return reply->element[index]->type;
	}
	
	return 0;
}

int RedisArrayStrdup( redisReply *reply , int index , char **pptr )
{
	if( reply->element[index]->type == REDIS_REPLY_STRING )
	{
		(*pptr) = strdup(reply->element[index]->str) ;
		if( pptr == NULL )
			return HIREDIS2WRAP_ERROR_ALLOC;
	}
	else
	{
		return reply->element[index]->type;
	}
	
	return 0;
}

int RedisArrayStringToInteger( redisReply *reply , int index , int *integer )
{
	if( reply->element[index]->type == REDIS_REPLY_STRING )
	{
		if( integer )
			(*integer) = atoi(reply->element[index]->str) ;
	}
	else
	{
		return reply->element[index]->type;
	}
	
	return 0;
}

void RedisFreeArray( redisReply **pp_reply )
{
	if( pp_reply && (*pp_reply) )
	{
		freeReplyObject( *pp_reply );
		(*pp_reply) = NULL ;
	}
	
	return;
}

int RedisGetError( redisContext *conn )
{
	return conn->err;
}

char *RedisGetErrorString( redisContext *conn )
{
	return conn->errstr;
}

